const path = require('path')
const Webpack = require('Webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {
    CleanWebpackPlugin
} = require('clean-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const WebpackBar = require('webpackbar')

module.exports = {
    // 控制显示信息
    stats: {
        chunks: false,
        chunkModules: false,
        errors: false,
        warnings: false,
        children: false,
        entrypoints: false,
        modules: false
    },
    // 入口(entry)
    entry: {
        vendor: path.resolve(__dirname, 'src/vendor.js'),
        main: path.resolve(__dirname, 'src/index.js')
    },
    // 输出(output)
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].[chunkhash:8].js',
        chunkFilename: '[name].[chunkhash:8].chunk.js'
    },
    // 启用 source map
    devtool: 'source-map',
    // loader
    module: {
        rules: [
            // 加载js 使用babel做转化
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: [{
                    loader: 'babel-loader',
                    options: {
                        sourceMap: true
                    }
                }]
            },
            // 加载ts
            {
                test: /\.tsx?$/,
                use: [{
                    loader: 'ts-loader'
                }]
            },
            // 加载 CSS
            {
                test: /\.css$/,
                use: [MiniCssExtractPlugin.loader, {
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }]
            },
            // 加载less
            {
                test: /\.less$/,
                use: [MiniCssExtractPlugin.loader, {
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "less-loader",
                    options: {
                        sourceMap: true
                    }
                }]
            },
            // 加载scss
            {
                test: /\.scss$/,
                use: [MiniCssExtractPlugin.loader, {
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "sass-loader",
                    options: {
                        sourceMap: true
                    }
                }]
            },
            // 加载sass
            {
                test: /\.sass$/,
                use: [MiniCssExtractPlugin.loader, {
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "sass-loader",
                    options: {
                        sourceMap: true
                    }
                }]
            },
            // 加载图片
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            // 加载字体
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            },
            //把jquery变成 $ 暴露到window
            {
                test: require.resolve('jquery'),
                use: 'expose-loader?$'
            },
            //把lodash变成 _ 暴露到window
            {
                test: require.resolve('lodash'),
                use: 'expose-loader?_'
            }
        ]
    },
    optimization: {
        minimizer: [
            // js压缩处理
            new UglifyJsPlugin({
                // 压缩选项
                uglifyOptions: {
                    // 关闭警告
                    warnings: false,
                    // 压缩规则
                    compress: {
                        // 移除console
                        drop_console: true,
                        // 移除debugger
                        drop_debugger: true
                    }
                },
                // 多线程压缩
                parallel: true,
                // 启用sourceMap
                sourceMap: true,
                // 压缩缓存
                cache: true
            })
        ],
        splitChunks: {
            // async、initial、all
            chunks: "async",
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            // 异步的按需加载模块最大的并行请求数，通过import()或者require.ensure()方式引入的模块，分离出来的包是异步加载的
            maxAsyncRequests: 5,
            // 初始加载网页的最大并行数.
            maxInitialRequests: 3,
            // name连接符，分离出来的新chunk的名字
            automaticNameDelimiter: '~',
            name: true,
            // 缓存组配置
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    minChunks: 1,
                    // 优先级
                    priority: 10,
                    minSize: 400000,
                    maxSize: 800000
                },
                default: {
                    chunks: 'all',
                    minChunks: 1,
                    priority: 0,
                    // 是否重用已经存在的模块
                    reuseExistingChunk: true,
                    minSize: 30000,
                    maxSize: 100000,
                }
            }
        },
    },
    // 插件(plugins)
    plugins: [
        // 打包前清理
        new CleanWebpackPlugin(),
        // 生成hash id
        new Webpack.HashedModuleIdsPlugin(),
        // 打包预编译
        new Webpack.optimize.ModuleConcatenationPlugin(),
        // 进度条插件
        new WebpackBar(),
        // html处理
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'src/index.html')
        }),
        // css提取
        new MiniCssExtractPlugin({
            filename: "[name].[chunkhash:8].css",
            chunkFilename: "[name].[chunkhash:8].chunk.css"
        }),
        // css压缩
        new OptimizeCSSAssetsPlugin({
            // 压缩规则
            cssProcessor: require('cssnano'),
            // 选项
            cssProcessorOptions: {
                map: {
                    // 不生成内联映射,这样配置就会生成一个source-map文件
                    inline: false,
                    // 向css文件添加source-map路径注释
                    // 如果没有此项压缩后的css会去除source-map路径注释
                    annotation: true
                }
            }
        }),
        // 复制引用资源
        new CopyWebpackPlugin([{
            from: path.resolve(__dirname, 'static'),
            to: 'static',
            ignore: ['.*']
        }])
    ]
}